package com.yinxing.netty.server;

import io.netty.channel.Channel;
import io.netty.channel.ChannelFutureListener;
import io.netty.util.AttributeKey;

import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

public class ChannelMap {

    private final AttributeKey<Long> userIdAttrKey = AttributeKey.valueOf("userIdAttrKey");

    /**
     * Channel容器(userId->channel)
     */
    private final ConcurrentHashMap<Long, Channel> channelMap = new ConcurrentHashMap<>();

    /**
     * 判断channel是否绑定用户
     * @param channel socket通道
     * @return true:绑定 false:未绑定
     */
    public boolean hasUser(Channel channel) {
        return channel.attr(userIdAttrKey).get() != null;
    }

    /**
     * 获取userId
     * @param channel socket通道
     */
    public Long getUserId(Channel channel) {
        return channel.attr(userIdAttrKey).get();
    }

    /**
     * userId与channel绑定
     * @param userId 用户Id
     * @param channel socket通道
     */
    public void setUserId(Long userId, Channel channel) {
        this.channelMap.put(userId, channel);
        channel.attr(userIdAttrKey).set(userId);
        channel.closeFuture().addListener((ChannelFutureListener) future -> channelMap.remove(userId));
    }

    /**
     * 根据userId获取当前用户绑定的Channel
     * @param userId 用户ID
     */
    public Channel getChannelByUserId(Long userId) {
        return this.channelMap.get(userId);
    }

    /**
     * 根据userId判断用户是否在线
     * @param userId 用户ID
     * @return true:在线 false:不在线
     */
    public boolean online(Long userId) {
        Channel channel = this.channelMap.get(userId);
        return channel != null && channel.isActive();
    }

    /**
     * 获取全部在线通道
     */
    public List<Channel> getOnlineChannels() {
        return this.channelMap
            .values()
            .stream()
            .filter(channel -> channel.isActive() && channel.isOpen())
            .collect(Collectors.toList());
    }
}
